// 伴生对象
// 1、首先名称会跟class类保持一致
// 2、另外会实现apply方法，在apply方法中会创建class类的对象
object Demo04StudentScala {
  def main(args: Array[String]): Unit = {
    // 通过new关键字可以创建类的对象
    val stu01: Demo04StudentScala = new Demo04StudentScala(1, "张三", 22, "男", "理科一班")

    println(stu01._id)
    println(stu01._name)

    // Scala中有一个比较特殊的类型 所有的变量的父类都是Any
    // Any 有两个子类 分别为： AnyRef、AnyVal
    // AnyVal 是任何值类型的父类
    // AnyRef 是任何引用类型的父类 类似Java中的Object
    val i: Int = 10
    val any: Any = i
    val anyVal: AnyVal = i

    val s: String = "abc"
    val any1: Any = s

    val any2: Any = stu01
    //    val anyVal2: AnyVal = stu01
    // 多态：父类引用指向子类对象
    val anyRef: AnyRef = stu01

    val stu02: Demo04StudentScala = new Demo04StudentScala(2, "张三2", 23, "男", "理科二班", "1888888xxxx")

    println(stu02._phoneNum)


    val stu03: Demo04StudentScala = new Demo04StudentScala(3, "张三3", 22, "男", "理科三班")
    // 默认会调用apply方法
    val stu04: Demo04StudentScala = Demo04StudentScala(4, "张三4", 22, "男", "理科三班")

  }

  def apply(id: Int, name: String, age: Int, gender: String, clazz: String):Demo04StudentScala = {
    new Demo04StudentScala(id: Int, name: String, age: Int, gender: String, clazz: String)
  }

  def apply(id: Int, name: String, age: Int, gender: String, clazz: String, phoneNum: String):Demo04StudentScala = {
    new Demo04StudentScala(id: Int, name: String, age: Int, gender: String, clazz: String, phoneNum: String)
  }
}

// 在Scala的class类中，由{}括起来的就是一个 构造方法
class Demo04StudentScala(id: Int, name: String, age: Int, gender: String, clazz: String) {
  println("默认构造方法")
  // Scala中定义变量、类的属性时 必须赋值 ---> 定义即赋值
  val _id: Int = id
  private var _name: String = name
  val _age: Int = age
  val _gender: String = gender
  val _clazz: String = clazz
  // 下划线 表示待会再赋值 这里的 String类型声明不能省略
  var _phoneNum: String = _

  // 重载构造方法
  def this(id: Int, name: String, age: Int, gender: String, clazz: String, phoneNum: String) {
    // 第一行代码必须通过this调用默认的构造方法
    this(id, name, age, gender, clazz)
    println("重载构造方法")
    _phoneNum = phoneNum
  }

  // 定义方法
  def getName: String = {
    this._name
  }

  def setName(s: String): Unit = {
    this._name = s
  }

  override def toString: String = {
    return s"StudentScala(id:${_id},name:${_name},age:${_age}"
  }

  // 定义方法
  def printStuInfo(): Unit = {
    println(this.id + "," + this.name + "," + this.age + "," + this.gender + "," + this.clazz)
  }
}
